React Native基础之箭头函数

前言

我们知道ES6允许使用“箭头”(=>)定义函数,习惯Java中函数定义之后,刚开始接触js,每次看到箭头函数都感觉怪怪的,那么为什么ES6要引入箭头函数呢,这个问题也一直困扰这我,虽然只要明白了箭头函数的语法,基本就可以正常的学习rn,使用rn开始开发,但是有些东西搞不清楚,心里头就感觉不踏实,今天咨询了一下做前后端开发的大学室友,才稍微明白了一点

引入箭头函数的原因

  1. 更简短的函数书写
  2. 对this的词法解析

更简短的函数书写

1
2
3
4
5
6
// 正常函数写法
[1,2,3].map(function (x) {
return x * x;
});
// 箭头函数写法
[1,2,3].map(x => x * x);

上面的箭头函数的第二种写法里面的x => x * x是等价于(x) => {return x * x},一个参数的时候小括号可以省略,后面的大括号如果省略的话,代表是一个隐式的返回值,具体这个箭头函数的语法可以看前一篇基础总结里面有提到

对this的词法解析(不绑定自己的 this,arguments,super)

这个相对于第一点,就不太好理解了,因为设计到this关键字,这个本身也是js语法的一个难点和痛点,js的this和java中的并不一样,所以对于初学者很容易被this搞的晕头转向,这里先不细说this,打算下一篇写写this关键字,先看测试代码吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
render() {
return (
<View style={styles.container}>
<Button
onPress={this.onPressNormal}
title="调用普通函数"
color="#841584" />
<Button
onPress={this.onPressArrow}
title="调用箭头函数"
color="#841584" />
</View>
)
}

onPressNormal() {
console.log('function normal :', this);
//console.log('function this state testFlag :', this.state.testFlag);
}
onPressArrow = () => {
console.log('function arrow:', this);
//console.log('function this state testFlag :', this.state.testFlag);
}

在上面的两个方法中,你会发现打印输出的this对象并不一样

1
2
ReactNativeJS: 'function normal :', { accessibilityComponentType: 'button',
ReactNativeJS: 'function arrow:', { props: { rootTag: 1 }

上面两个通过不同语法定义的方法,一个this对象指向的是button本身,一个指向的是该方法定义所在的全局对象,这样说可能并不直观,那我们进一步改一下上面两个方法输出,我在构造函数里面先定义一个state状态变量testFlag,默认值为false,然后在两个方法中分别输出该state变量:

1
2
3
4
5
6
7
8
onPressNormal() {
//console.log('function normal :', this);
console.log('function this state testFlag :', this.state.testFlag);
}
onPressArrow = () => {
//console.log('function arrow:', this);
console.log('function this state testFlag :', this.state.testFlag);
}

你会发现箭头函数输出如下:

1
ReactNativeJS: 'function this state testFlag :', false

但是普通定义的函数就直接error了,提示:

1
undefined is not an object(evaluting 'this.state.testFlag')

同样的输出,只是不同的函数定义,在这种情况下差别就体现出来了,造成这的原因也就是函数里面的this指代的对象是不一样的,这也是引入箭头函数的第二个原因,箭头函数会捕获其所在的上下文的this对象,作为自己的this值,从而确保代码运行结果和你期望的的结果一致,当然你如果确实习惯了java这种方法定义,不喜欢用箭头函数,那么通过bind绑定this也是可以解决的

结尾

这就是箭头函数带来的两个比较大的改变,但是使用箭头函数的时候也有几点需要注意的:

  • this对象的指向是可变的,但是在箭头函数中,它是固定的,函数体内的this对象,绑定定义时所在的对象,而不是使用时所在的对象
  • 不可以当作构造函数,不可以使用new命令